﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Kinect;
using TSL.Model;
using Microsoft.Win32;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace TSL
{
    /// <summary>
    /// Interaction logic for TranslateWindow.xaml
    /// </summary>
    public partial class TranslateWindow : Window
    {
        KinectModule kin;
        private JoinFrame headJointFrame, leftJointFrame, rightJointFrame, shoulderLeftJointFrame, shoulderRightJointFrame, hipLeftJointFrame, hipRightJointFrame;
        private TSL.Model.Frame jointFrame;
        private List<TSL.Model.Frame> totalFrame;
        private Dictionary<string, string> outputDictionary;
        private Gesture gesture;
        private int frameCounter = 0;
        private bool isRecive = false;
        private Neural network;
        private NeuralModule nn;
        private String outputNo;

        public TranslateWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            kinectSensorChooser1.KinectSensorChanged += new DependencyPropertyChangedEventHandler(kinectSensorChooser1_KinectSensorChanged);
            network = new Neural();
            nn = new NeuralModule();
            frameCounter = 0;
            totalFrame = new List<TSL.Model.Frame>();
        }

        void kinectSensorChooser1_KinectSensorChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            KinectSensor oldSensor = (KinectSensor)e.OldValue;
            //stop the old sensor
            if (oldSensor != null)
            {
                oldSensor.Stop();
                //oldSensor.AudioSource.Stop();
            }

            KinectSensor newSensor = (KinectSensor)e.NewValue;
            //kin = new KinectModule(newSensor);

            if (newSensor != null)
            {
                kin = new KinectModule(kinectSensorChooser1.Kinect);
                //logBlock.Text = kin.getHeadData();
                newSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
                newSensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);
                newSensor.SkeletonStream.Enable();
                newSensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(newSensor_AllFramesReady);
                try
                {
                    newSensor.Start();
                }
                catch (System.IO.IOException)
                {
                    kinectSensorChooser1.AppConflictOccurred();
                }
            }
        }

        void newSensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            if (kin.CheckReadyStance())
            {
                overlayText.Text = "In ready Stance";
                if (frameCounter == 0)
                {
                    LogBox.Text += "User is in ready stance. \r\n";
                }
                headJointFrame = new JoinFrame();
                headJointFrame.X = kin.getHeadPos("x"); headJointFrame.Y = kin.getHeadPos("y"); headJointFrame.Z = kin.getHeadPos("z");

                leftJointFrame = new JoinFrame();
                leftJointFrame.X = kin.getLeftHandPos("x"); leftJointFrame.Y = kin.getLeftHandPos("y"); leftJointFrame.Z = kin.getLeftHandPos("z");

                rightJointFrame = new JoinFrame();
                rightJointFrame.X = kin.getRightHandPos("x"); rightJointFrame.Y = kin.getRightHandPos("y"); rightJointFrame.Z = kin.getRightHandPos("z");

                shoulderLeftJointFrame = new JoinFrame();
                shoulderLeftJointFrame.X = kin.getLeftShoulderPos("x"); shoulderLeftJointFrame.Y = kin.getLeftShoulderPos("y"); shoulderLeftJointFrame.Z = kin.getLeftShoulderPos("z");

                shoulderRightJointFrame = new JoinFrame();
                shoulderRightJointFrame.X = kin.getRightShoulderPos("x"); shoulderRightJointFrame.Y = kin.getRightShoulderPos("y"); shoulderRightJointFrame.Z = kin.getRightShoulderPos("z");

                hipLeftJointFrame = new JoinFrame();
                hipLeftJointFrame.X = kin.getLeftHipPos("x"); hipLeftJointFrame.Y = kin.getLeftHipPos("y"); hipLeftJointFrame.Z = kin.getLeftHipPos("z");

                hipRightJointFrame = new JoinFrame();
                hipRightJointFrame.X = kin.getRightHipPos("x"); hipRightJointFrame.Y = kin.getRightHipPos("y"); hipRightJointFrame.Z = kin.getRightHipPos("z");

                jointFrame = new TSL.Model.Frame();
                jointFrame.FrameNo = frameCounter;
                jointFrame.Head = headJointFrame;
                jointFrame.HandLeft = leftJointFrame; jointFrame.HandRight = rightJointFrame;
                jointFrame.ShoulderLeft = shoulderLeftJointFrame; jointFrame.ShoulderRight = shoulderRightJointFrame;
                jointFrame.HipLeft = hipLeftJointFrame; jointFrame.HipRight = hipRightJointFrame;
                totalFrame.Add(jointFrame);
                frameCounter += 1;
                isRecive = true;
            }
            else
            {
                if (isRecive)
                {
                    LogBox.Text += "Stop Recive. \r\n";
                    gesture = new Gesture();
                    gesture.GestureFrames = totalFrame;
                    gesture.TotalFrame = totalFrame.Count;
                    LogBox.Text += "Get Gesture Complete \r\n";
                    isRecive = false;
                    //double actual = network.Run(gesture);
                    //double round = Math.Round(actual, 2, MidpointRounding.AwayFromZero);
                    //LogBox.Text += "Actual Output is " + actual + " round up to " + round + "\r\n";
                    outputNo = "";
                    ArrayList actual = nn.TestNeural(gesture);
                    LogBox.Text += "Actual Output : \r\n";
                    foreach (double d in actual)
                    {
                        LogBox.Text += "        " + Math.Round(d, 0, MidpointRounding.AwayFromZero) + " >>> (" + d + ")\r\n";
                        outputNo += Math.Round(d, 0, MidpointRounding.AwayFromZero);
                    }
                    LogBox.Text += "==================================\r\n";
                    overlayText.Text = "Get output : "+outputNo + " = "+nn.findMeaning(outputNo);
                    NoticeText.Text = outputNo + " = " + nn.findMeaning(outputNo);
                }
            }
        }

        void StopKinect(KinectSensor sensor)
        {
            if (sensor != null)
            {
                sensor.Stop();
                //sensor.AudioSource.Stop();
            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            StopKinect(kinectSensorChooser1.Kinect);
        }

        private void Button_Click_1(object sender, System.Windows.RoutedEventArgs e)
        {
            var mainmenu = new MainMenu();
            mainmenu.Show();
            this.Close();
        }

        private void loadNetwork_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog filePicker = new OpenFileDialog();
            filePicker.Filter = "TSL (*.tsl) |*.tsl|" + "All files (*.*)|*.*"; 
            if (filePicker.ShowDialog().Value)
            {
                if (filePicker.CheckPathExists && filePicker.CheckPathExists)
                {
                    String path = filePicker.FileName;
                    path = path.Replace(@"\", @"\\");
                    if (nn.LoadNeural(path))
                    {
                        LogBox.Text += "Load network complete \r\n";
                    }
                }
            }
        }
    }
}
